<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
      <el-form-item label="文件名前缀" prop="prefix">
        <el-input v-model="queryParams.prefix" placeholder="如 acd.img的ac" clearable />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="success" plain icon="el-icon-caret-left" @click="handleReturn"
          :disabled="this.path_list.length === 0">返回上一级</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-download" @click="handleBatchDownload"
          :disabled="this.selectFiles.length === 0">批量下载</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="el-icon-download" @click="handleBatchDel"
          :disabled="this.selectFiles.length === 0">批量删除</el-button>
      </el-col>
      <el-col :span="1.5">
         <el-upload  class="upload-demo" action="" :show-file-list="false" :on-change="changeFile">
          <el-button type="primary" plain icon="el-icon-upload">点击上传</el-button>
        </el-upload>
      </el-col>
      <div style="font-size:14px;height:36px;line-height:36px;color:#74bcff;margin-left: 20px;">
        当前路径:{{ this.path_list.length ? this.path_list[this.path_list.length - 1] : '首页' }}
        <right-toolbar :showSearch.sync="showSearch" @queryTable="handleQuery"></right-toolbar>
      </div>


    </el-row>

    <el-table v-loading="loading" :data="file_list" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="" align="center" prop="" :show-overflow-tooltip="true" width="60">
        <template slot-scope="scope">
          <div v-if="scope.row.size"><img src="@/assets/images/file.svg" alt="light" style="width: 30px;height: 30px;">
          </div>
          <div v-else>
            <img src="@/assets/images/package.svg" alt="light" style="width: 30px;height: 30px;">
            <!-- {{ scope.row.name }} -->
          </div>
        </template>
      </el-table-column>
      <el-table-column label="文件名" align="left" prop="name" :show-overflow-tooltip="true" width="450">
        <template slot-scope="scope">
          <div v-if="scope.row.size">{{ scope.row.name }}</div>
          <div v-else style="text-decoration:underline;cursor: pointer;" @click="handleClickPackage(scope.row.name)">
            {{ scope.row.name }}
          </div>
        </template>
      </el-table-column>
      <el-table-column label="图片预览" align="center" prop="url">
        <template slot-scope="scope">
          <div v-show="scope.row.size">
            <el-popover trigger="hover" placement="bottom" width="400">
              <img slot="reference" :src="scope.row.url" style="width: 60px;" v-if="scope.row.url" />
              <img :src="scope.row.url" style="width: 300px" v-if="scope.row.url" />
            </el-popover>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="文件大小" align="center" prop="size" :show-overflow-tooltip="true">
        <template slot-scope="scope">
          <div v-show="scope.row.size">
            {{ scope.row.size > 1024 * 1024 * 1024 ? (scope.row.size / 1024 / 1024 / 1024).toFixed(2) + 'GB' :
              (scope.row.size >
                1024 * 1024 ? (scope.row.size / 1024 / 1024).toFixed(2) + 'MB' : (scope.row.size > 1024 ?
                  (scope.row.size / 1024).toFixed(2) + 'KB' : scope.row.size + 'B')) }}
          </div>
        </template>
      </el-table-column>
      <el-table-column label="存储级别" align="center" prop="storageClass" :show-overflow-tooltip="true">
        <template slot-scope="scope">
          <div>
            <el-tag effect="light" v-if="scope.row.size && scope.row.storageClass == 'Standard'">{{ scope.row.storageClass
              | formatStorageClass }}</el-tag>
            <el-tag effect="light" type="success"
              v-if="scope.row.size && scope.row.storageClass == 'Infrequent Access'">{{ scope.row.storageClass |
                formatStorageClass }}</el-tag>
            <el-tag effect="light" type="info" v-if="scope.row.size && scope.row.storageClass == 'Archive'">{{
              scope.row.storageClass | formatStorageClass }}</el-tag>
            <el-tag effect="light" type="warning" v-if="scope.row.size && scope.row.storageClass == 'Cold Archive'">{{
              scope.row.storageClass | formatStorageClass }}</el-tag>
            <el-tag effect="light" type="error" v-if="scope.row.size && scope.row.storageClass == 'Deep Cold Archive'">{{
              scope.row.storageClass | formatStorageClass }}</el-tag>
          </div>
        </template>
      </el-table-column>
      <!-- <el-table-column label="上传类型" align="center" prop="type" :show-overflow-tooltip="true">
        <template slot-scope="scope">
          <div>
            <el-tag effect="light" v-if="scope.row.size">{{ scope.row.type}}</el-tag>
          </div>
        </template>
      </el-table-column> -->
      <el-table-column label="最近修改时间" align="center" prop="lastModified" :show-overflow-tooltip="true" />
      <el-table-column label="操作" align="center" prop="url" :show-overflow-tooltip="true">
        <template slot-scope="scope">
          <el-button size="mini" style="font-size: 13px;" type="text" @click="handleDownload(scope.row.url)"
            v-show="scope.row.url && scope.row.size">
            下载
          </el-button>
          <el-button size="mini" style="font-size: 13px;" type="text" @click="handleRename(scope.row.name)">
            重命名
          </el-button>
          <el-button size="mini" style="font-size: 13px;" type="text" @click="handleDelete(scope.row.name)">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <div style="width:100%;height:30px;margin-top: 10px;">
      <div style="width:40%;height:100%;float:right;text-align:right">
        <el-select v-model="queryParams.maxKeys" filterable placeholder="请选择" style="width:80px;margin-right: 10px;"
          @change="handlePageSizeChange">
          <el-option v-for="item in maxKeys_list" :key="item.value" :label="item.label" :value="item.value">
          </el-option>
        </el-select>
        <el-button :disabled="currentPageNum === 0" type="primary" plain icon="el-icon-arrow-left" size="mini"
          @click="handleMarker">上一页</el-button>
        <el-button :disabled="this.queryParams.nextMarker === null ? true : false" type="primary" plain
          icon="el-icon-arrow-right" size="mini" @click="handleNextMarker">下一页</el-button>
      </div>
    </div>

    <!-- 文件重命名 -->
    <el-dialog :loading="renameLoading" title="文件重命名" :visible.sync="dialogRename" width="1000px" append-to-body>
      <el-form ref="renameForm" :model="renameForm" :rules="rules" label-width="80px">
        <el-form-item label="旧文件名" prop="oldName">
          <el-input v-model="renameForm.oldName" :disabled="true" />
        </el-form-item>
        <el-form-item label="新文件名" prop="newName">
          <el-input v-model="renameForm.newName" placeholder="请输入新文件名" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="confirmRename">确 认</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { saveAs } from 'file-saver';
import { Loading } from 'element-ui'
import JSZip from 'jszip'
import FileSaver from 'file-saver'
import axios from 'axios';
import { stsToken } from "@/api/oss/stsToken"
const OSS = require('ali-oss')
export default {
  name: "oss-manage",
  data() {
    return {
      //上传文件路径
      fileList:'',
      // 
      delfiles: [],
      // 要删除的文件夹名称
      folderName: null,
      // 文件夹-批量下载标记
      getDownloadFilesMark: false,
      // 文件夹-全部删除标记
      getDelFilesMark: false,
      // 文件夹-文件删除集合
      folder_del_list: [],
      // 重命名loading
      renameLoading: false,
      // 删除文件结果集合
      delResult_list: [],
      // 拷贝文件结果集合
      copyResult_list: [],
      // 文件全部列举成功
      getAllFileMark: false,
      // 拷贝列表
      copy_list: [],
      zip: new JSZip(),
      promises: [],
      // 下载的文件
      download_list: [],
      // 文件数量
      fileNum: 0,
      // 文件夹数量
      folderNum: 0,
      // 重命名弹出框
      dialogRename: false,
      renameForm: {
        oldName: null,
        newName: null
      },
      // 选中行的名称
      name_list: [],
      // 选中行
      selectFiles: [],
      // 文件夹列表
      path_list: [],
      // 页码
      marker_list: [],
      // oss返回的文件列表
      file_list: [],
      // 分页列举
      currentPageNum: 0,
      pageNum: 0,
      pageSize: 20,
      client: null,//oss云服务器对象
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 选中项目名数组
      names: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 项目表格数据
      containerTypelList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 最大值列表
      maxKeys_list: [
        { label: 10, value: 10 },
        { label: 20, value: 20 },
        { label: 50, value: 50 },
        { label: 100, value: 100 },
        { label: 200, value: 200 },
        { label: 500, value: 500 },
        { label: 1000, value: 1000 },
      ],
      // 查询参数
      queryParams: {
        maxKeys: 10,
        prefix: null,
        nextMarker: null,
        marker: null
      },
      // 表单校验
      rules: {
        newName: [
          { required: true, message: "新名称不能为空", trigger: "blur" }
        ],
      },
      //上传文件列表
      
    };
  },
  filters: {
    formatStorageClass(key) {
      const map = {
        'Standard': '标准存储',
        'Infrequent Access': '低频访问',
        'Archive': '归档存储',
        'Cold Archive': '冷归档存储',
        'Deep Cold Archive': '深度冷归档存储'
      }
      return map[key]
    },
  },
  watch: {
    getDownloadFilesMark: {
      async handler(val) {
        if (val) {
          console.log("循环的下载对象", this.download_list)
          for (var i = 0; i < this.download_list.length; i++) {
            console.log(i)
            let arr = this.download_list[i].url.split('/')
            arr = arr.slice(3)
            let result = arr.join('/')
            // 如果文件存在中文则转码
            if (result.includes('%')) {
              result = decodeURI(result)
            }
            // 放入数组
            let fileTemp = {
              fvUrl: this.download_list[i].url,
              fvName: result
            }
            // 是文件-
            this.download_file_list.push(fileTemp)
          }
          let costTime = this.download_list.length / 10
          if (costTime > 60) {
            costTime = (costTime / 60).toFixed(1) + '分钟'
          } else {
            costTime = costTime + '秒'
          }
          this.renameLoading.close()
          this.renameLoading = Loading.service({
            lock: true,
            color: '#7c6050',
            text: '文件整理完成,共' + this.download_list.length + '个文件，大约需要' + costTime + ',文件下载中……',
            background: 'rgba(0, 0, 0, 0.8)'
          })
          console.log("列举完成，所需要下载的文件为", this.download_file_list)
          // 压缩包名称
          var zipName = `文件压缩包_${new Date().getTime()}`
          // 打包下载
          this.loadZip(this.download_file_list, zipName)
        }
      }
    },
    getDelFilesMark: {
      async handler(val) {
        if (val) {
          // 计算花费时间
          let costTime = this.folder_del_list.length / 10
          if (costTime > 60) {
            costTime = (costTime / 60).toFixed(1) + '分钟'
          } else {
            costTime = costTime + '秒'
          }
          // 准备开始删除，提供交互
          this.renameLoading = Loading.service({
            lock: true,
            color: '#7c6050',
            text: '文件整理完成，' + this.folderName + '下共' + this.folder_del_list.length + '个文件，大约需要' + costTime + ',文件删除中……',
            background: 'rgba(0, 0, 0, 0.8)'
          })
          // 执行删除动作，获取执行结果
          let index = 0
          let mark = false
          let text = ''
          while (index < this.folder_del_list.length) {
            let delResult = await this.handleDel(this.folder_del_list[index].name)
            this.delResult_list.push(delResult)
            index++
          }
          // 加工删除结果
          for (let i = 0; i < this.delResult_list.length; i++) {
            if (this.delResult_list[i] !== undefined) {
              mark = true
              text = text + `<p style="color:red">${this.delResult_list[i].failObjectName}文件删除失败</p>`
            }
          }
          // 结果交互
          if (mark) {
            text = '文件夹删除异常！' + text
            this.$confirm(text, '文件夹删除结果', {
              confirmButtonText: '确定',
              dangerouslyUseHTMLString: true,
              showCancelButton: false,
              type: 'error',
            })
            //  **下载删除的原因**
            //  构造CSV头部信息
            let csvContent = "删除报错原因\n";
            // 根据列表数据构造每一行的内容
            for (let item of this.delResult_list) {
              csvContent += `${item.failObjectName}\n`;
            }
            // 创建Blob对象
            const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8' });
            // 调用FileSaver库保存文件
            saveAs(blob, 'delerror.csv');
          } else {
            text = '文件夹' + this.folderName + '删除成功！'
            this.$confirm(text, '文件夹删除结果', {
              confirmButtonText: '确定',
              dangerouslyUseHTMLString: true,
              showCancelButton: false,
              type: 'success',
            })
          }
          this.renameLoading.close()
          this.QuerylistFile('refresh')
        }
      }
    },
    getAllFileMark: {
      async handler(val) {
        if (val) {
          console.log("mark转true")
          if (this.copy_list.length === 0) {
            this.$message.info("文件夹下没有文件")
            return
          } else {
            this.$message.info("文件整理完成，共" + this.copy_list.length + "个文件，开始拷贝……")
            // 初略计算一张拷贝花费时间100毫秒 转秒再除以1000 得到秒数,拷贝和删除时间相同
            let costTime = this.copy_list.length / 5
            console.log(costTime)
            if (costTime > 60) {
              costTime = (costTime / 60).toFixed(1) + '分钟'
            } else {
              costTime = costTime + '秒'
            }
            console.log(costTime)
            // 更新提示框内容
            this.renameLoading.close()
            this.renameLoading = Loading.service({
              lock: true,
              color: '#7c6050',
              text: '文件整理完成共' + this.copy_list.length + '个文件，重命名大约需要花费' + costTime + ',开始拷贝……',
              background: 'rgba(0, 0, 0, 0.8)'
            })
            // 开始拷贝
            let index = 0
            while (index < this.copy_list.length) {
              let copyResult = await this.handleCopy(this.copy_list[index].name)
              this.copyResult_list.push(copyResult)
              index++
            }
            // 拷贝结束，更新提示
            this.renameLoading.close()
            this.renameLoading = Loading.service({
              lock: true,
              color: '#7c6050',
              text: '文件整理完成共' + this.copy_list.length + '个文件，大约需要' + costTime + ',开始删除原文件……',
              background: 'rgba(0, 0, 0, 0.8)'
            })
            // 开始删除
            let index2 = 0
            while (index2 < this.copy_list.length) {
              let delResult = await this.handleDel(this.copy_list[index2].name)
              this.delResult_list.push(delResult)
              index2++
            }
            // 删除结束，更新提示
            this.renameLoading.close()

            // const copyResult = await Promise.all(this.copy_list.map(async (v) => await this.handleCopy(v.name)));
            // this.$message.info("文件拷贝完成，开始删除原文件……")
            // const delResult = await Promise.all(this.copy_list.map(async (v) => await this.handleDel(v.name)));
            console.log("拷贝结果为", this.copyResult_list)
            console.log("删除结果为", this.delResult_list)
            let text = ''
            let mark = false
            for (let i = 0; i < this.copyResult_list.length; i++) {
              if (this.copyResult_list[i] !== undefined) {
                mark = true
                text = text + `<p style="color:red">${this.copyResult_list[i].failObjectName}文件拷贝失败</p>`
              }
            }
            for (let i = 0; i < this.delResult_list.length; i++) {
              if (this.delResult_list[i] !== undefined) {
                mark = true
                text = text + `<p style="color:red">${this.delResult_list[i].failObjectName}文件删除失败</p>`
              }
            }

            if (mark) {
              text = '重命名异常！' + text
              this.$confirm(text, '文件夹重命名结果', {
                confirmButtonText: '确定',
                dangerouslyUseHTMLString: true,
                showCancelButton: false,
                type: 'error',
              })
              // 构造CSV头部信息
              let csvContent = "拷贝报错原因\n";
              // 根据列表数据构造每一行的内容
              for (let item of this.copyResult_list) {
                csvContent += `${item.failObjectName}\n`;
              }
              // 创建Blob对象
              const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8' });
              // 调用FileSaver库保存文件
              saveAs(blob, 'copyerror.csv');
              // 构造CSV头部信息
              csvContent = "删除报错原因\n";
              // 根据列表数据构造每一行的内容
              for (let item of this.delResult_list) {
                csvContent += `${item.failObjectName}\n`;
              }
              // 创建Blob对象
              blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8' });
              // 调用FileSaver库保存文件
              saveAs(blob, 'delerror.csv');
            } else {
              text = '重命名成功！' + text
              this.$confirm(text, '文件夹重命名结果', {
                confirmButtonText: '确定',
                dangerouslyUseHTMLString: true,
                showCancelButton: false,
                type: 'success',
              })
            }

            this.dialogRename = false
            // this.handleQuery()
            this.QuerylistFile('refresh')
          }

        }
      },
      immediate: true

    }
  },
  created() {
    this.getStsToken()
  },
  methods: {
    // 压缩包
    async loadZip(fileArr, zipName = '下载文件') {
      let index = 0
      this.zip = new JSZip() // 创建实例对象
      // 遍历生成下载文件
      while (index < fileArr.length) {
        await this.createFile(fileArr[index])
        index++
      }
      Promise.all(this.promises).then(() => {
        // 生成zip 文件
        this.zip.generateAsync({
          type: 'blob',  // 文件格式
          compression: 'DEFLATE', // STORE: 默认不压缩， DEFLATE：需要压缩
          compressionOptions: {
            level: 9 // 压缩等级 1~9   1 压缩速度最快， 9 最优压缩方式
          }
        }).then((res) => {
          console.log(res)
          FileSaver.saveAs(res, `${zipName}.zip`) // 使用FileSaver.saveAs保存文件，文件名可自定义
        })
      })
      this.renameLoading.close()
    },
    // 创建文件
    async createFile(item) {
      const promise = await this.getFile(item.fvUrl).then((res) => {
        const fvName = item.fvName + ''
        // 创建文件用file()，创建文件夹用 floder()
        this.zip.file(fvName, res.data, {
          binary: true
        })
      })
      this.promises.push(promise)
      console.log("执行完毕")
    },
    async getFile(fvUrl) {
      return await new Promise((resolve, reject) => {
        axios(fvUrl, {
          method: 'get',  // get请求
          responseType: 'blob' // 返回的数据会被强制转为blob类型 ，转换成arraybuffer 也行
        }).then((res) => {
          resolve(res) // 将下载的文件返回
        }).catch(err => {
          reject(err)
        })
      })
    },
    //获取上传的图片
    changeFile(file) {
      console.log('##file',file);
      let fileData = file.raw
      this.fileList = fileData
      console.log('##filelist',fileData);
      this.handleUpLoad()
      // const imgData = new FormData()
      // imgData.append('packageFile', this.fileList)
    },
    //上传文件到oss
    async handleUpLoad() {
      //上传时的自定义
      const headers = {
        // 指定Object的存储类型。
        'x-oss-storage-class': 'Standard',
        // 指定Object的访问权限。
        'x-oss-object-acl': 'private',
        // 通过文件URL访问文件时，指定以附件形式下载文件，下载后的文件名称定义为example.txt。
        'Content-Disposition': 'attachment; filename="example.txt"',
        // 设置Object的标签，可同时设置多个标签。
        'x-oss-tagging': 'Tag1=1&Tag2=2',
        // 指定PutObject操作时是否覆盖同名目标Object。此处设置为true，表示禁止覆盖同名Object。
        'x-oss-forbid-overwrite': 'false',
      }
      try {
        const result = await this.client.put(`${this.path_list[this.path_list.length - 1]}${this.fileList.name}`,this.fileList)
        this.QuerylistFile();
      } catch (error) {
        console.log('###error',error);
        return error;
      }
    },

    // 批量删除文件/文件夹
    handleBatchDel() {
      const h = this.$createElement
      this.$confirm(h('div', [h('p', '删除不可逆，请再三确认！'), h('p', '确定批量删除' + this.names + '吗？')]), '提示', {
        distinguishCancelAndClose: true,
        confirmButtonText: '确定',
        cancelButtonText: '取消',
      })
        .then(() => {
          this.confirmBatchDel()
        })
        .catch(() => {
          this.$message.info("已取消批量删除")
        })

    },
    async getFilesByFolderName(name) {
      const list = await this.client.list({
        "max-keys": 1000,
        prefix: this.delFolderName,
        marker: name ? name : null,
      });
      let mark = false

      // this.copy_list = list.objects || [];
      // 如果获取到的列表长度为1000，再根据最后一个去获取下一个page的列表
      if (list.objects.length === 1000) {
        this.delfiles.push(...list.objects)
        console.log("执行连接", this.delfiles)
        console.log(list.objects[999].name)

        let nameList = this.delfiles.map(item => item.name)
        console.log("用于删除的nameList", nameList)
        this.packageDelResult.push(await this.handleBatchDelFile(nameList))
        this.delfiles = []
        console.log("等待删除")
        this.getFilesByFolderName(list.objects[999].name)
      } else {
        this.delfiles.push(...list.objects)
        let nameList = this.delfiles.map(item => item.name)
        console.log("用于删除的nameList", nameList)
        this.packageDelResult.push(await this.handleBatchDelFile(nameList))
        console.log("删除完毕", this.delfiles)
        this.delfiles = []
        this.$message.success("批量删除成功")
        this.QuerylistFile('refresh')
      }
      // if(mark){

      // }
    },
    async delFileByFileType(i) {
      // 判断是文件还是文件夹
      if (this.selectFiles[i].name[this.selectFiles[i].name.length - 1] === '/') {
        console.log("是文件夹", this.selectFiles[i].name)
        this.delFolderName = this.selectFiles[i].name
        // 文件夹的话，先获取这个文件夹名下所有文件，然后批量删除
        await this.getFilesByFolderName()
        console.log(1)
        // let nameList = list.objects.map(item => item.name)
        // packageDelResult.push ( await this.handleBatchDelFile(nameList) )
      } else {
        console.log("是文件", this.selectFiles[i].name)
        // 文件可以直接调用删除接口
        this.fileDelResult.push(await this.handleDel(this.selectFiles[i].name))
      }
    },
    async confirmBatchDel() {
      this.renameLoading = Loading.service({
        lock: true,
        color: '#7c6050',
        text: '文件统计中,大约花费1~10s,请稍后……',
        background: 'rgba(0, 0, 0, 0.8)'
      })

      console.log("处理选中的行", this.selectFiles)
      this.packageDelResult = []
      this.fileDelResult = []
      let index = 0
      this.renameLoading = Loading.service({
        lock: true,
        color: '#7c6050',
        text: '删除中,请稍后……',
        background: 'rgba(0, 0, 0, 0.8)'
      })
      while (index < this.selectFiles.length) {
        await this.delFileByFileType(index)
        index++
        console.log(index)
      }
      this.renameLoading.close()

      let mark = false
      let text = ''
      let type = 'success'
      for (let i = 0; i < this.fileDelResult.length; i++) {
        if (this.fileDelResult[i] !== undefined) {
          mark = true
          text = text + `<p style="color:red">${this.fileDelResult[i].failObjectName}文件删除失败！</p>`
          console.log(this.fileDelResult[i])
        }
      }
      if (mark) {
        text = '部分文件删除出现异常！' + text
        type = 'error'
      } else {
        text = '<p style="color:green">删除成功！</p>'
        type = 'success'
      }
      // this.renameLoading.close()
      // this.$confirm(text,'文件删除结果', {
      //   confirmButtonText: '确定',
      //   dangerouslyUseHTMLString:true,
      //   showCancelButton: false,
      //   type: type,
      // })
      this.QuerylistFile('refresh')

      console.log("打印批量删除结果:文件：", this.fileDelResult, "文件夹：", this.packageDelResult)
    },
    // 替换字符串中的字符
    replaceAll(str, find, replace) {
      return str.replace(new RegExp(find, 'g'), replace);
    },
    async handleCopy(name) {
      let newName = this.replaceAll(name, this.renameForm.oldName, this.renameForm.newName)
      // 接口调用
      try {
        const result = await this.client.copy(newName, name);
      } catch (error) {
        error.failObjectName = name;
        return error;
      }
    },
    // 批量删除
    async handleBatchDelFile(nameList) {
      try {
        // const result = await client.deleteMulti(['exampleobject-1', 'exampleobject-2', 'testfolder/sampleobject.txt'], {quiet: true});
        const result = await this.client.deleteMulti(nameList, { quiet: true });
      } catch (error) {
        error.failObjectName = name;
        return error;
      }
    },
    // 单文件删除
    async handleDel(name) {
      try {
        const result = await this.client.delete(name);
      } catch (error) {
        error.failObjectName = name;
        return error;
      }
    },
    /** 获取所有文件 */
    async getAllFile(name) {
      const list = await this.client.list({
        "max-keys": 1000,
        prefix: this.renameForm.oldName,
        marker: name ? name : null,
      });
      console.log(list.objects)
      console.log(list.objects.length)

      // this.copy_list = list.objects || [];
      // 如果获取到的列表长度为1000，再根据最后一个去获取下一个page的列表
      if (list.objects.length === 1000) {
        console.log("执行连接")
        this.copy_list.push(...list.objects)
        this.getAllFile(list.objects[999].name)
      } else {
        this.copy_list.push(...list.objects)
        this.getAllFileMark = true
        console.log("整理完毕")
      }
      console.log("当前拷贝的列表为", this.copy_list)
    },
    /** 文件夹重命名 */
    async confiremRenamePackage() {
      this.getAllFileMark = false
      this.$message("开始整理文件……")
      this.renameLoading = Loading.service({
        lock: true,
        text: '正在整理文件',
        background: 'rgba(0, 0, 0, 0.8)'
      })
      // 获取全部的文件
      this.getAllFile()
    },
    /** 文件重命名 */
    async confiremRenameFile() {
      console.log("确认重命名", this.renameForm)
      // 将srcobject.txt拷贝至同一Bucket下的destobject.txt。
      await this.client.copy(this.renameForm.newName, this.renameForm.oldName).then(async (res) => {
        console.log('拷贝成功', res.res);
        // 删除srcobject.txt。
        const deleteResult = await this.client.delete(this.renameForm.oldName);
        console.log("删除结果", deleteResult);
        if (res.res.statusCode === 200 && deleteResult.res.statusCode === 204) {
          this.$message({
            type: 'success',
            message: '重命名成功'
          });
          this.dialogRename = false
          this.handleQuery()
        }
      }).catch((err) => {
        this.$message.error("重命名失败", err)
      })
    },
    /** 确认重命名 */
    confirmRename() {
      if (this.renameForm.oldName[this.renameForm.oldName.length - 1] === '/') {
        console.log("是文件夹")
        this.confiremRenamePackage()
      } else {
        console.log("是文件")
        this.confiremRenameFile()
      }
    },
    /** 重命名文件 */
    handleRename(name) {
      this.dialogRename = true
      this.renameForm.oldName = name
      this.renameForm.newName = name
    },
    /** 删除文件  */
    async handleDelete(name) {
      this.$modal.confirm('确认删除"' + name + '"？').then(function () {
      }).then(() => {
        if (name[name.length - 1] === '/') {
          console.log("是文件夹")
          this.folderName = name
          this.confiremDeletePackage(name)
        } else {
          console.log("是文件")
          this.confiremDeleteFile(name)
        }

      }).catch(() => { });
    },
    async handleDel(name) {
      try {
        await this.client.delete(name);
      } catch (error) {
        error.failObjectName = name;
        return error;
      }
    },
    /** 获取要删除的文件夹下的所有文件 */
    async getDelFiles(name) {
      const list = await this.client.list({
        "max-keys": 1000,
        prefix: this.folderName,
        marker: name ? name : null,
      });
      console.log(list.objects)
      console.log(list.objects.length)

      // this.folder_del_list = list.objects || [];
      // 如果获取到的列表长度为1000，再根据最后一个去获取下一个page的列表
      if (list.objects.length === 1000) {
        this.folder_del_list.push(...list.objects)
        this.getAllFile(list.objects[999].name)
      } else {
        this.folder_del_list.push(...list.objects)
        this.getDelFilesMark = true
      }
    },
    /** 确认删除文件夹 */
    async confiremDeletePackage() {
      this.getAllFileMark = false
      this.getDelFiles()
    },
    /** 确认删除文件 */
    async confiremDeleteFile(name) {
      await this.client.delete(name).then((res) => {
        console.log("删除成功", res)
        this.$message({
          type: 'success',
          message: '删除成功'
        });
        //123
        // this.query()
        this.QuerylistFile('refresh')
      }).catch((err) => {
        this.$message.error("删除失败", err)
      })
    },
    // 获取全部下载文件
    async getAllDownloadFile(index) {
      if (this.selectFiles[index].url !== null) {
        console.log("文件")

        // 取url第三个‘/’后的作为建立文件夹的依据 如 cut/123/123.jpg
        let arr = this.selectFiles[index].url.split('/')
        arr = arr.slice(3)
        let result = arr.join('/')
        // 如果文件存在中文则转码
        if (result.includes('%')) {
          result = decodeURI(result)
        }
        // 放入数组
        let fileTemp = {
          fvUrl: this.selectFiles[index].url,
          fvName: result
        }
        this.download_file_list.push(fileTemp)
      } else {
        console.log("文件夹")
        this.downloadFolderName = this.selectFiles[index].name
        // 如果是文件夹,获取这一单层文件夹下的子文件夹和文件，如果是文件再列举塞到一个文件list里面
        await this.getFileByFolderName()
      }
    },
    // 批量下载文件
    async handleBatchDownload() {
      this.renameLoading = Loading.service({
        lock: true,
        text: '正在统计文件，请稍后……',
        background: 'rgba(0, 0, 0, 0.8)'
      })
      this.download_file_list = []
      // 如果有选中行
      if (this.selectFiles) {
        let index = 0
        // 异步-等待全部集合都进去下载集合
        while (index < this.selectFiles.length) {
          await this.getAllDownloadFile(index)
          index++
        }
        // 全部塞到下载集合中后，开始下载
        this.getDownloadFilesMark = true
      } else {
        this.$message.warning("请先选择要下载的文件~")
      }
    },
    /** 获取要下载的文件夹下的所有文件 */
    async getDownloadFiles(name) {
      const list = await this.client.list({
        "max-keys": 1000,
        prefix: this.downloadFolderName,
        marker: name ? name : null,
      });
      console.log(list.objects)
      console.log(list.objects.length)
      // 如果获取到的列表长度为1000，再根据最后一个去获取下一个page的列表
      if (list.objects.length === 1000) {
        this.download_list.push(...list.objects)
        this.getDownloadFiles(list.objects[999].name)
      } else {
        this.download_list.push(...list.objects)
      }
    },
    /** 根据文件夹name获取子文件和子文件夹 */
    async getFileByFolderName() {
      this.getDownloadFilesMark = false
      // 获取文件夹下列举的所有文件
      await this.getDownloadFiles()
    },
    /** 回退 */
    async handleReturn() {
      let path = ''
      // console.log("回退前",this.path_list)
      if (this.path_list.length > 0) {
        this.path_list.pop()
      }
      // console.log("回退后",this.path_list)
      if (this.path_list.length) {
        path += this.path_list[this.path_list.length - 1]
      } else {
        path = ''
      }

      if (this.queryParams.prefix) {
        path += this.queryParams.prefix
      }
      await this.client.list({
        "max-keys": this.queryParams.maxKeys,
        delimiter: '/',
        // marker: packageName ,
        prefix: path       // 文件名前缀（检索条件）
      }).then(async (res) => {
        this.currentPageNum = 0
        // this.currentPageNum --
        this.pageNum = 0
        this.marker_list = []
        this.file_list = res.objects
        if (res.prefixes) {
          for (var i = 0; i < res.prefixes.length; i++) {
            let temp = {
              name: res.prefixes[i],
              size: null,
              storageClass: null,
              type: null,
              url: null,
              lastModified: null
            }
            this.file_list.push(temp)

          }
        }
        // Uint8Array转String 获取marker和nextRemarker 用于分页
        await this.setPageMarker(res.res.data)
      }).finally(() => {
        this.loading = false
      })
    },
    /** 点击文件夹 */
    async handleClickPackage(packageName) {
      this.path_list.push(packageName)
      let path = ''
      // this.pa
      path += this.path_list[this.path_list.length - 1]
      if (this.queryParams.prefix) {
        path += this.queryParams.prefix
      }
      await this.client.list({
        "max-keys": this.queryParams.maxKeys,
        delimiter: '/',
        prefix: path       // 文件名前缀（检索条件）
      }).then(async (res) => {
        console.log(res)
        this.currentPageNum = 0
        // this.currentPageNum --
        this.pageNum = 0
        this.marker_list = []
        this.file_list = res.objects
        console.log("objects", this.file_list)

        if (res.prefixes) {
          for (var i = 0; i < res.prefixes.length; i++) {
            let temp = {
              name: res.prefixes[i],
              size: null,
              storageClass: null,
              type: null,
              url: null,
              lastModified: null
            }
            console.log("加入prefixes", temp)
            this.file_list.push(temp)
          }
          console.log("加入prefixes", this.file_list)
        }
        // Uint8Array转String 获取marker和nextRemarker 用于分页
        await this.setPageMarker(res.res.data)
      }).finally(() => {
        this.loading = false
        this.$forceUpdate()
      })
    },
    /** pageSize改变  */
    async handlePageSizeChange() {
      let path = ''
      // console.log("回退后",this.path_list)
      if (this.path_list.length) {
        path += this.path_list[this.path_list.length - 1]
      } else {
        path = ''
      }

      if (this.queryParams.prefix) {
        path += this.queryParams.prefix
      }
      await this.client.list({
        "max-keys": this.queryParams.maxKeys,
        delimiter: '/',
        // marker: this.queryParams.nextMarker ,每页展示数量的改变不需要
        prefix: path       // 文件名前缀（检索条件）
      }).then(async (res) => {
        this.currentPageNum = 0
        this.pageNum = 0
        this.marker_list = []
        this.file_list = res.objects
        if (res.prefixes) {
          for (var i = 0; i < res.prefixes.length; i++) {
            let temp = {
              name: res.prefixes[i],
              size: null,
              storageClass: null,
              type: null,
              url: null,
              lastModified: null
            }
            this.file_list.push(temp)

          }
        }
        // Uint8Array转String 获取marker和nextRemarker 用于分页
        await this.setPageMarker(res.res.data)
      }).finally(() => {
        this.loading = false
      })
    },
    /** oss文件下载到本地 */
    handleDownload(row) {
      let url = row
      const a = document.createElement('a')
      a.href = url
      a.download = row.bomList // 下载后文件名
      a.style.display = 'none'
      document.body.appendChild(a)
      a.click() // 点击下载
      document.body.removeChild(a) // 下载完成移除元素
      // window.location.href = row.bomList
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.QuerylistFile();
    },
    // 设置页码
    async setPageMarker(data) {
      const decoder = new TextDecoder();
      const responseXML = decoder.decode(data)
      var parser = new DOMParser();
      //读取返回字符串
      var _xml = parser.parseFromString(responseXML, "text/xml");
      // 解析后根据标签名的属性来判断是否存在值
      if (_xml.getElementsByTagName("Marker").length === 0) {
        this.queryParams.marker = null
      } else {
        this.queryParams.marker = _xml.getElementsByTagName("Marker")[0].innerHTML
      }
      // 放入上一页的页码
      if (this.marker_list.indexOf(this.queryParams.marker) === -1) {
        this.marker_list.push(this.queryParams.marker)
        this.pageNum++
      }

      if (_xml.getElementsByTagName("NextMarker").length === 0) {
        this.queryParams.nextMarker = null
      } else {
        this.queryParams.nextMarker = _xml.getElementsByTagName("NextMarker")[0].innerHTML
      }
      // console.log("页码管理",this.marker_list,"总页数",this.pageNum,"当前页",this.currentPageNum)
    },
    /** 上一页 */
    async handleMarker() {
      let path = ''
      if (this.path_list.length) {
        path += this.path_list[this.path_list.length - 1]
      } else {
        path = ''
      }
      if (this.queryParams.prefix) {
        path += this.queryParams.prefix
      }
      await this.client.list({
        delimiter: '/',
        "max-keys": this.queryParams.maxKeys,
        marker: this.marker_list[this.currentPageNum - 1],
        prefix: path       // 文件名前缀（检索条件）
      }).then(async (res) => {
        this.currentPageNum--
        this.file_list = res.objects
        if (res.prefixes) {
          for (var i = 0; i < res.prefixes.length; i++) {
            let temp = {
              name: res.prefixes[i],
              size: null,
              storageClass: null,
              type: null,
              url: null,
              lastModified: null
            }
            this.file_list.push(temp)

          }
        }
        // Uint8Array转String 获取marker和nextRemarker 用于分页
        await this.setPageMarker(res.res.data)
      }).finally(() => {
        this.loading = false
      })
    },
    /** 下一页 */
    async handleNextMarker() {
      let path = ''
      if (this.path_list.length) {
        path += this.path_list[this.path_list.length - 1]
      } else {
        path = ''
      }
      if (this.queryParams.prefix) {
        path += this.queryParams.prefix
      }
      await this.client.list({
        delimiter: '/',
        "max-keys": this.queryParams.maxKeys,
        marker: this.queryParams.nextMarker,
        prefix: path       // 文件名前缀（检索条件）
      }).then(async (res) => {
        this.currentPageNum++
        this.file_list = res.objects
        if (res.prefixes) {
          for (var i = 0; i < res.prefixes.length; i++) {
            let temp = {
              name: res.prefixes[i],
              size: null,
              storageClass: null,
              type: null,
              url: null,
              lastModified: null
            }
            this.file_list.push(temp)

          }
        }
        // Uint8Array转String 获取remark和nextRemark 用于分页
        await this.setPageMarker(res.res.data)
      }).finally(() => {
        this.loading = false
      })
    },
    /** 检索 */
    async QuerylistFile(type) {
      let path = ''
      // console.log("回退后",this.path_list)
      if (this.path_list.length) {
        path += this.path_list[this.path_list.length - 1]
      } else {
        path = ''
      }

      if (this.queryParams.prefix) {
        path += this.queryParams.prefix
      }
      await this.client.list({
        "max-keys": this.queryParams.maxKeys,
        delimiter: '/',
        marker: type == 'refresh' ? null : this.queryParams.nextMarker,
        prefix: path       // 文件名前缀（检索条件）
      }).then(async (res) => {
        this.currentPageNum = 0
        this.pageNum = 0
        this.marker_list = []
        this.file_list = res.objects
        if (res.prefixes) {
          for (var i = 0; i < res.prefixes.length; i++) {
            let temp = {
              name: res.prefixes[i],
              size: null,
              storageClass: null,
              type: null,
              url: null,
              lastModified: null
            }
            this.file_list.push(temp)

          }
        }
        // Uint8Array转String 获取marker和nextRemarker 用于分页
        await this.setPageMarker(res.res.data)
      }).finally(() => {
        this.loading = false
      })
    },
    /** 获取bucket里的文件列表 */
    async listFile() {
      // 初始化
      this.queryParams.marker = null
      this.queryParams.nextMarker = null
      // 调用oss接口
      await this.client.list({
        "max-keys": this.queryParams.maxKeys, // 获取多少条
        prefix: this.queryParams.prefix,        // 文件名前缀（检索条件）
        delimiter: '/'
      }).then(async (res) => {
        console.log(res)
        this.file_list = res.objects
        if (res.prefixes) {
          for (var i = 0; i < res.prefixes.length; i++) {
            let temp = {
              name: res.prefixes[i],
              size: null,
              storageClass: null,
              type: null,
              url: null,
              lastModified: null
            }
            this.file_list.push(temp)

          }
        }
        // Uint8Array转String 获取remark和nextRemarker 用于分页
        await this.setPageMarker(res.res.data)
        this.currentPageNum = 0
      }).finally(() => {
        this.loading = false
      })
    },
    /** 从后台获取sts临时权限 */
    getStsToken(){
      const params={
        bucketName:'genius-prod1'
      }
      // 接口调用
      stsToken(params).then((res) => {
        // console.log(res)
        //调用接口获取到之后
        this.client = new OSS({
          accessKeyId: res.data.accessKey,
          accessKeySecret: res.data.secretKey,
          stsToken: res.data.securityToken,
          // 写死 测试-深圳 正式 杭州
          region:'oss-cn-hangzhou',
          // bucket:'genius-inner-use',
          bucket:'genius-prod1',
          // accessKeyId:'LTAI4Fzhk3aC5K1dCWWPUphK',
          // accessKeySecret:'Ogyt5AHb8u34MnCzLNNZ9E7N3ONn3g',
          // accessKeyId:'STS.NUZG1WqPm6HR7UHcXNYrB7rke',
          // accessKeySecret:'EgZvUqA2KHx7dLoVGkG5seQd5Ggo6u9sysQbSRwMBCpf',
          // stsToken:'CAIS9gF1q6Ft5B2yfSjIr5bvDIvjnI9MgYq5NXP5h1gbVf1u2LfAhzz2IHhMeXBgCesetP4xmWpY6P0flqZ8RplEWFeBd8x049EPqVr59j4icm7sv9I+k5SANTW5KXyShb3/AYjQSNfaZY3eCTTtnTNyxr3XbCirW0ffX7SClZ9gaKZ8PGD6F00kYu1bPQx/ssQXGGLMPPK2SH7Qj3HXEVBjt3gX6wo9y9zmmpzBtkWC1wKqk7BI+dygGPX+MZkwZqUYesyuwel7epDG1CNt8BVQ/M909vccoWqe7oHGWwMLvUjcY7SPr8cPKxRiI6YnH6pUPXg7dFWaK4UagAF4LCFYra5j+pWOpDXbcEq9rzYIqzd/1UsmxasYDnIStD03IyRL8P2rGS9Bz2Gs2UIeyHdePMKqzDg1oOOFvRUZccLq7eI9LGnOzy9d2yHlD58g9FHaBZGofJru0wwG/4Ewgw2QV0m09BGaPtGS9V+AzBgDLSWzuxEJ1uYUklxdqSAA',
          // 定时刷新token
          refreshSTSToken: async () => {
            const refreshToken = await stsToken(params);
            return {
              accessKeyId: refreshToken.data.accessKey,
              accessKeySecret: refreshToken.data.secretKey,
              stsToken: refreshToken.data.securityToken,
            };
          },
          // 刷新临时访问凭证的时间间隔，单位为毫秒。
          refreshSTSTokenInterval: 300000,
        })
      }).catch((err) => {
        this.$message.err("stsToken获取失败!,原因：" + err.message)
      }).finally(() => {
        //   //接口调用的finally中获取一下bucket的文件列表
        this.listFile()
      })
    },
    // 取消按钮
    cancel() {
      this.dialogRename = false;
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.name_list = selection.map(item => item.name)
      this.selectFiles = selection
    },
  }
};
</script>
<style lang="scss">
.el-input--medium .el-input__icon {
  height: 28px;
  line-height: 28px;
}

.el-input--medium .el-input__inner {
  height: 28px;
  line-height: 28px;
}

.formTitle {
  width: 100%;
  text-align: center;
  margin: 15px 0 15px 0;
  font-weight: border;
  font-size: 20px
}
</style>
